import UIKit

class TextView: UIViewController, UITextViewDelegate {
    
    // 主文本输入视图
    private var textView: UITextView!
    // 字数统计标签
    private var counterLabel: UILabel!
    // 占位提示标签
    private var placeholderLabel: UILabel!
    
    // 记录键盘高度用于布局调整
    private var keyboardHeight: CGFloat = 0
    // 保存文本视图原始底部约束，用于键盘显示/隐藏时恢复
    private var originalTextViewBottomConstraint: NSLayoutConstraint?
    private var originalLabelBottomConstraint: NSLayoutConstraint?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .systemBackground
        setupUI()           // 初始化UI组件
        setupConstraints()  // 设置布局约束
        setupKeyboardObservers()  // 注册键盘通知监听
    }
    
    deinit {
        // 移除键盘通知监听，防止内存泄漏
        removeKeyboardObservers()
    }
    
    private func setupUI() {
        // 初始化文本输入视图
        textView = UITextView()
        textView.delegate = self
        textView.font = UIFont.systemFont(ofSize: 16)
        textView.textColor = .black
        textView.backgroundColor = .white
        textView.layer.cornerRadius = 12          // 圆角
        textView.layer.borderWidth = 1            // 边框宽度
        textView.layer.borderColor = UIColor.systemGray3.cgColor  // 边框颜色
        textView.textContainerInset = UIEdgeInsets(top: 16, left: 12, bottom: 16, right: 12)  // 文本内边距
        textView.translatesAutoresizingMaskIntoConstraints = false  // 使用自动布局
        view.addSubview(textView)
        
        // 初始化占位提示标签
        placeholderLabel = UILabel()
        placeholderLabel.text = "请输入内容（最多500字）"
        placeholderLabel.font = UIFont.systemFont(ofSize: 16)
        placeholderLabel.textColor = .systemGray  // 灰色文字
        placeholderLabel.numberOfLines = 0        // 允许多行显示
        placeholderLabel.isHidden = !textView.text.isEmpty  // 有文本时隐藏占位符
        placeholderLabel.translatesAutoresizingMaskIntoConstraints = false
        textView.addSubview(placeholderLabel)
        
        // 初始化字数统计标签
        counterLabel = UILabel()
        counterLabel.font = UIFont.systemFont(ofSize: 14)
        counterLabel.textColor = .systemGray
        counterLabel.text = "0/500"  // 初始字数显示
        counterLabel.translatesAutoresizingMaskIntoConstraints = false
        textView.addSubview(counterLabel)
    }
    
    private func setupConstraints() {
        let margin: CGFloat = 20  // 视图边距
        
        // 设置文本视图底部约束，保存原始约束用于键盘处理
        originalTextViewBottomConstraint = textView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -margin)
        originalLabelBottomConstraint = counterLabel.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -margin)
        
        // 激活文本视图约束
        NSLayoutConstraint.activate([
            // 文本视图上下左右约束
            textView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: margin),
            textView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: margin),
            textView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -margin),
            originalTextViewBottomConstraint!,
            
            // 占位标签约束：相对于文本视图的位置
            placeholderLabel.leadingAnchor.constraint(equalTo: textView.leadingAnchor, constant: 12),
            placeholderLabel.topAnchor.constraint(equalTo: textView.topAnchor, constant: 16),
            placeholderLabel.trailingAnchor.constraint(equalTo: textView.trailingAnchor, constant: -12),
            
            // 字数统计标签约束：位于文本视图内底部
            counterLabel.leadingAnchor.constraint(equalTo: textView.leadingAnchor, constant: 12),
            originalLabelBottomConstraint!,
            counterLabel.trailingAnchor.constraint(equalTo: textView.trailingAnchor, constant: -12),
        ])
    }
    
    // MARK: - 键盘处理
    private func setupKeyboardObservers() {
        // 注册键盘显示通知
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil)
        // 注册键盘隐藏通知
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: UIResponder.keyboardWillHideNotification, object: nil)
    }
    
    private func removeKeyboardObservers() {
        // 移除键盘通知监听
        NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillShowNotification, object: nil)
        NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillHideNotification, object: nil)
    }
    
    @objc private func keyboardWillShow(_ notification: Notification) {
        // 从通知中获取键盘高度
        guard let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue else { return }
        let keyboardRect = keyboardFrame.cgRectValue
        keyboardHeight = keyboardRect.height
        
        // 获取键盘动画信息
        let duration = notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double ?? 0.3
        let curve = notification.userInfo?[UIResponder.keyboardAnimationCurveUserInfoKey] as? UInt ?? UIView.AnimationOptions.curveEaseInOut.rawValue
        let options = UIView.AnimationOptions(rawValue: curve)
        
        // 调整文本视图底部约束，避免被键盘遮挡
        originalTextViewBottomConstraint?.constant = -keyboardHeight - 20
        originalLabelBottomConstraint?.constant = -keyboardHeight - 20
        
        // 约束动画
        // 使用与键盘相同的动画参数调整布局
        UIView.animate(withDuration: 3, delay: 0, options: options, animations: {
            self.view.layoutIfNeeded()  // 强制立即更新布局
        }, completion: nil)
    }
    
    @objc private func keyboardWillHide(_ notification: Notification) {
        // 获取键盘隐藏动画信息
        let duration = notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double ?? 0.3
        let curve = notification.userInfo?[UIResponder.keyboardAnimationCurveUserInfoKey] as? UInt ?? UIView.AnimationOptions.curveEaseInOut.rawValue
        let options = UIView.AnimationOptions(rawValue: curve)
        
        // 恢复文本视图原始底部约束
        originalTextViewBottomConstraint?.constant = -20
        originalLabelBottomConstraint?.constant = -20
        
        // 使用与键盘相同的动画参数恢复布局
        UIView.animate(withDuration: duration, delay: 0, options: options, animations: {
            self.view.layoutIfNeeded()  // 强制立即更新布局
        }, completion: nil)
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        
        // 确保所有子视图布局已正确更新
        view.setNeedsLayout()
        view.layoutIfNeeded()
    }
    
    // MARK: - UITextViewDelegate 方法
    func textViewDidChange(_ textView: UITextView) {
        // 根据文本内容是否为空显示/隐藏占位标签
        placeholderLabel.isHidden = !textView.text.isEmpty
        
        // 字数统计与限制（最多500字）
        let maxLength = 10
        if textView.text.count > maxLength {
            // 超过最大长度时截断文本
            textView.text = String(textView.text.prefix(maxLength))
        }
        // 更新字数显示
        counterLabel.text = "\(textView.text.count)/\(maxLength)"
    }
    
    func textViewDidBeginEditing(_ textView: UITextView) {
        // 开始编辑时的回调，可添加自定义逻辑
    }
    
    func textViewShouldReturn(_ textView: UITextView) -> Bool {
        // 点击返回键时收起键盘
        textView.resignFirstResponder()
        return true
    }
}
